package com.igroupes.ovineherd.raw.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.igroupes.ovineherd.dto.UserInfo;
import com.igroupes.ovineherd.dto.response.RelationshipResponse;
import com.igroupes.ovineherd.entity.DataModelRelationshipEntity;
import com.igroupes.ovineherd.entity.DataModelVersionEntity;
import com.igroupes.ovineherd.exception.ModelException;
import com.igroupes.ovineherd.model.dto.RelationshipRequest;
import com.igroupes.ovineherd.query.ModelDataJsonAttributeQuery;
import com.igroupes.ovineherd.query.ModelDataJsonTableQuery;
import com.igroupes.ovineherd.raw.service.IDataModelRelationshipService;
import com.igroupes.ovineherd.raw.service.raw.DataModelRelationshipService;
import com.igroupes.ovineherd.raw.service.raw.DataModelTableService;
import com.igroupes.ovineherd.raw.service.raw.DataModelVersionService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DataModelRelationshipServiceImpl implements IDataModelRelationshipService {

    @Autowired
    private DataModelTableService dataModelTableService;
    @Autowired
    private DataModelVersionService dataModelVersionService;
    @Autowired
    private DataModelRelationshipService dataModelRelationshipService;
    @Override
    public Boolean modelBatchAddRelationship(List<RelationshipRequest> relationshipRequests, UserInfo userInfo) {
        checkParams(relationshipRequests, userInfo);
        return checkValue(relationshipRequests, userInfo);
    }

    @Override
    public List<RelationshipResponse> getRelationship(UserInfo userInfo) {
        Long versionId = dataModelVersionService.getModelVersionEdit(userInfo.getId());
        QueryWrapper<DataModelRelationshipEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(DataModelRelationshipEntity::getAddUser, userInfo.getId())
            .eq(DataModelRelationshipEntity::getVersionId, versionId);
        return dataModelRelationshipService.list(wrapper).stream().map(dataModelRelationshipEntity -> {
                RelationshipResponse relationship = new RelationshipResponse();
                relationship.setId(dataModelRelationshipEntity.getId());
                relationship.setSourceFiledId(dataModelRelationshipEntity.getSourceAttributeId());
                relationship.setSourceTableId(dataModelRelationshipEntity.getSourceTableId());
                relationship.setSourceType(dataModelRelationshipEntity.getSourceType());
                relationship.setTargetFiledId(dataModelRelationshipEntity.getTargetAttributeId());
                relationship.setTargetTableId(dataModelRelationshipEntity.getTargetTableId());
                relationship.setTargetType(dataModelRelationshipEntity.getTargetType());
                return relationship;
            }
        ).collect(Collectors.toList());
    }

    @Data
    @AllArgsConstructor
    static class TableAttribute{
        private Long tableId;
        private List<Long> attributes;
    }
    /**
     * 校验参数
     * @param relationshipRequests 模型关系
     * @return
     */
    private void checkParams(List<RelationshipRequest> relationshipRequests, UserInfo userInfo){
        List<ModelDataJsonTableQuery> modelDataJsonTableQueries =  dataModelTableService.tableJsonAll(userInfo.getId());
        Map<Long, TableAttribute> tableMap = new HashMap<>();
        for (ModelDataJsonTableQuery modelData :
                modelDataJsonTableQueries) {
            tableMap.put(modelData.getId(),
                    new TableAttribute(modelData.getId(),modelData.getFields().stream().map(ModelDataJsonAttributeQuery::getId).collect(Collectors.toList())));
        }
        for (RelationshipRequest relationshipRequest :
                relationshipRequests) {
            TableAttribute tableAttributeSource = tableMap.get(relationshipRequest.getSourceTableId());
            if(ObjectUtil.isNull(tableAttributeSource)){
                throw new ModelException("传值错误，".concat(relationshipRequest.getSourceTableId().toString()));
            }
            if(!tableAttributeSource.getAttributes().contains(relationshipRequest.getSourceFiledId())){
                throw new ModelException("传值错误，".concat(relationshipRequest.getSourceFiledId().toString()));
            }
            TableAttribute tableAttributeTarget = tableMap.get(relationshipRequest.getTargetTableId());
            if(ObjectUtil.isNull(tableAttributeTarget)){
                throw new ModelException("传值错误，".concat(relationshipRequest.getTargetTableId().toString()));
            }
            if(!tableAttributeTarget.getAttributes().contains(relationshipRequest.getTargetFiledId())){
                throw new ModelException("传值错误，".concat(relationshipRequest.getTargetFiledId().toString()));
            }
        }
    }


    /**
     * 添加关系值
     * @param relationshipRequests
     * @param userInfo
     */
    private Boolean checkValue(List<RelationshipRequest> relationshipRequests, UserInfo userInfo){
        Long versionId = dataModelVersionService.getModelVersionEdit(userInfo.getId());
        //获取自己的所有关系
        UpdateWrapper<DataModelRelationshipEntity> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(DataModelRelationshipEntity::getAddUser, userInfo.getId())
            .set(DataModelRelationshipEntity::getIsDel, System.currentTimeMillis());
        dataModelRelationshipService.update(wrapper);
        List<DataModelRelationshipEntity> dataModelRelationshipEntities = new ArrayList<>();
        for (RelationshipRequest relationshipRequest :
                relationshipRequests) {
            DataModelRelationshipEntity entity = new DataModelRelationshipEntity();
            entity.setSourceTableId(relationshipRequest.getSourceTableId());
            entity.setSourceAttributeId(relationshipRequest.getSourceFiledId());
            entity.setSourceType(relationshipRequest.getSourceType());
            entity.setTargetTableId(relationshipRequest.getTargetTableId());
            entity.setTargetAttributeId(relationshipRequest.getTargetFiledId());
            entity.setTargetType(relationshipRequest.getTargetType());
            entity.setAddUser(userInfo.getId());
            entity.setVersionId(versionId);
            dataModelRelationshipEntities.add(entity);
        }
        dataModelRelationshipService.saveBatch(dataModelRelationshipEntities, 50);
        return true;
    }
}
